package cn.smbms.config;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Properties;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.ui.freemarker.FreeMarkerConfigurationFactory;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;

import cn.smbms.interceptor.SysInterceptor;

import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

@EnableWebMvc
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(basePackages = "cn.smbms.controller")
public class SpringMvcConfig extends WebMvcConfigurerAdapter {
	@Override
	public void configureMessageConverters(
			List<HttpMessageConverter<?>> converters) {
		converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
		// fastjson
		FastJsonConfig config = new FastJsonConfig();
		config.setDateFormat("yyyy-MM-dd HH:mm:ss");
		FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
		converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/json;charset=UTF-8"));
		converter.setFastJsonConfig(config);
		converters.add(converter);
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		//registry.addResourceHandler("/webjars/**").addResourceLocations("/webjars/");
		registry.addResourceHandler("/statics/**").addResourceLocations("classpath:/statics/");
	}

	@Resource
	private DataSource dataSource;

	@Bean
	public ViewResolver viewResolverFreemarker() {
		FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
		resolver.setViewClass(FreeMarkerView.class);
		resolver.setCache(false);
		resolver.setSuffix(".html");
		resolver.setExposeSpringMacroHelpers(true);
		resolver.setExposeRequestAttributes(true);
		resolver.setExposeSessionAttributes(true);
		resolver.setRequestContextAttribute("request");
		resolver.setContentType("text/html; charset=UTF-8");
		resolver.setOrder(1);
		resolver.setViewNames("*");
		return resolver;
	}

	@Bean
	public FreeMarkerConfigurer freemarkerConfig() throws IOException,
			TemplateException {
		// FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
		FreeMarkerConfigExtend configurer = new FreeMarkerConfigExtend();
		//
		FreeMarkerConfigurationFactory factory = new FreeMarkerConfigurationFactory();
		factory.setTemplateLoaderPaths("classpath:/templates/","/WEB-INF/templates/");
		factory.setDefaultEncoding("UTF-8");
		freemarker.template.Configuration configuration = factory.createConfiguration();
		configuration.setClassicCompatible(true);
		configuration.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
		configurer.setConfiguration(configuration);
		//
		Properties settings = new Properties();
		settings.put("template_update_delay", "0");
		settings.put("default_encoding", "UTF-8");
		settings.put("number_format", "0.##");
		settings.put("datetime_format", "yyyy-MM-dd HH:mm:ss");
		settings.put("classic_compatible", true);
		settings.put("template_exception_handler", "html_debug");		
		configurer.setFreemarkerSettings(settings);
		//
		return configurer;
	}

	@Bean
	public ViewResolver viewResolverJsp() {
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setPrefix("/WEB-INF/jsp/");
		viewResolver.setSuffix(".jsp");
		viewResolver.setOrder(2);
		// viewResolver.setViewClass(JstlView.class);
		// viewResolver.setViewNames("*");
		return viewResolver;
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new SysInterceptor()).addPathPatterns("/jsp/**");
	}

	@Bean
	public MultipartResolver multipartResolver() {
		MultipartResolver multipartResolver = new StandardServletMultipartResolver();
		return multipartResolver;
	}

   @Bean
   public SimpleMappingExceptionResolver simpleMappingExceptionResolver()
   {
       SimpleMappingExceptionResolver b = new SimpleMappingExceptionResolver();
       Properties mappings = new Properties();
       mappings.put("org.springframework.web.servlet.PageNotFound", "page-404");
       mappings.put("org.springframework.dao.DataAccessException", "data-access");
       //shiro UnauthorizedException
       mappings.put("org.apache.shiro.authz.UnauthorizedException", "jsp/shiro");
       b.setExceptionMappings(mappings);
       return b;
     }
}
